package pl.polidea.imf.blackberry.util;

import java.util.Enumeration;
import java.util.Hashtable;

import org.json.me.JSONException;
import org.json.me.JSONObject;

import pl.polidea.imf.common.java.model.Condition;
import pl.polidea.imf.common.java.model.bindings.ConditionCategoryPropertyBinding;

public class PhoneStatusChangeChecker {

	public static final Null NULL = new Null();

	private Hashtable lastValuesForProperty;

	private PhoneStatusChangeListener listener;

	private Thread myThread;

	public synchronized void registerListener(PhoneStatusChangeListener listener) {
		this.listener = listener;
	}

	private boolean isRunning = true;

	public PhoneStatusChangeChecker() {
		lastValuesForProperty = new Hashtable();
		lastValuesForProperty.put(Condition.KEYS.BATERRY_LEVEL, NULL);
		lastValuesForProperty.put(Condition.KEYS.BATERRY_PLUGGED, NULL);
		lastValuesForProperty.put(Condition.KEYS.SCREEN_HEIGHT, NULL);
		lastValuesForProperty.put(Condition.KEYS.SCREEN_NUMBER_OF_COLORS, NULL);
		lastValuesForProperty.put(Condition.KEYS.SCREEN_ORIENTATION, NULL);
		lastValuesForProperty.put(Condition.KEYS.SCREEN_WIDTH, NULL);
		myThread = new Thread() {
			public void run() {
				while (isRunning()) {
					rescan();
					ThreadHelper.tryToSleep(TIME_PERIODS.ONE_MINUTE);
				}
			}
		};
		myThread.start();
	}

	private void rescan() {
		JSONObject result = new JSONObject();
		boolean changed = false;
		Enumeration keys = lastValuesForProperty.keys();
		String key;
		Object lastValue;
		Object currValue;
		while (keys.hasMoreElements()) {
			key = (String) keys.nextElement();
			lastValue = lastValuesForProperty.get(key);
			currValue = DeviceStatusHelper.getValueForKey(key);
			if (!lastValue.equals(currValue)) {
				changed = true;
				String category = (String) ConditionCategoryPropertyBinding.INSTANCE.getValue(key);
				if (category != null) {
					JSONObject categoryObj = null;
					if (result.has(category)) {

						categoryObj = result.optJSONObject(category);

					} else {
						categoryObj = new JSONObject();
						try {
							result.put(category, categoryObj);
						} catch (JSONException e) {
							/* cannot occur */
							e.printStackTrace();
						}
					}

					try {
						if (categoryObj != null) {
							categoryObj.put(key, currValue);
						}
					} catch (JSONException e) {
						/* cannot occur */
						e.printStackTrace();
					}
				} else {

				}
				lastValuesForProperty.put(key, currValue == null ? NULL : currValue);
			}
		}
		if (changed && listener != null) {
			listener.statusChanged(result);
		}

	}

	private synchronized boolean isRunning() {
		return isRunning;
	}

	public synchronized void stop() {
		isRunning = false;
	}

	public static class Null {
		public String toString() {
			return "null";
		}
	}

	public interface PhoneStatusChangeListener {
		void statusChanged(JSONObject state);
	}

}
